<!DOCTYPE html><html lang="zh-CN"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1"><meta name="format-detection" content="telephone=no"><meta name="apple-mobile-web-app-capable" content="yes"><meta name="apple-mobile-web-app-status-bar-style" content="black"><link rel="icon" href="/images/icons/favicon-16x16.png?v=2.8.0" type="image/png" sizes="16x16"><link rel="icon" href="/images/icons/favicon-32x32.png?v=2.8.0" type="image/png" sizes="32x32"><meta name="description" content="以技能为导向的工作态度、以兴趣为导向的人际交流">
<meta property="og:type" content="website">
<meta property="og:title" content="ljyxsg的技术成长录">
<meta property="og:url" content="https://lou_jianyang.gitee.io/index.html">
<meta property="og:site_name" content="ljyxsg的技术成长录">
<meta property="og:description" content="以技能为导向的工作态度、以兴趣为导向的人际交流">
<meta property="og:locale" content="zh_CN">
<meta property="article:author" content="ljyxsg">
<meta property="article:tag" content="ljyxsg的技术成长录">
<meta name="twitter:card" content="summary"><title>ljyxsg的技术成长录</title><link ref="canonical" href="https://lou_jianyang.gitee.io/index.html"><link rel="dns-prefetch" href="https://cdn.jsdelivr.net"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@5.12.1/css/all.min.css" type="text/css"><link rel="stylesheet" href="/css/index.css?v=2.8.0"><link rel="stylesheet" href="css/custom.css"><script>var Stun = window.Stun || {};
var CONFIG = {
  root: '/',
  algolia: undefined,
  assistSearch: undefined,
  fontIcon: {"prompt":{"success":"fas fa-check-circle","info":"fas fa-arrow-circle-right","warning":"fas fa-exclamation-circle","error":"fas fa-times-circle"},"copyBtn":"fas fa-copy"},
  sidebar: {"offsetTop":"20px","tocMaxDepth":6},
  header: {"enable":true,"showOnPost":true,"scrollDownIcon":false},
  postWidget: {"endText":true},
  nightMode: {"enable":true},
  back2top: {"enable":true},
  codeblock: {"style":"default","highlight":"light","wordWrap":false},
  reward: false,
  fancybox: false,
  zoomImage: {"gapAside":"20px"},
  galleryWaterfall: undefined,
  lazyload: false,
  pjax: undefined,
  externalLink: {"icon":{"enable":true,"name":"fas fa-external-link-alt"}},
  shortcuts: undefined,
  prompt: {"copyButton":"复制","copySuccess":"复制成功","copyError":"复制失败"},
  sourcePath: {"js":"js","css":"css","images":"images"},
};

window.CONFIG = CONFIG;</script><meta name="generator" content="Hexo 6.3.0"></head><body><div class="container" id="container"><header class="header" id="header"><div class="header-inner"><nav class="header-nav header-nav--fixed"><div class="header-nav-inner"><div class="header-nav-menubtn"><i class="fas fa-bars"></i></div><div class="header-nav-menu"><div class="header-nav-menu-item"><a class="header-nav-menu-item__link" href="/"><span class="header-nav-menu-item__icon"><i class="fas fa-home"></i></span><span class="header-nav-menu-item__text">首页</span></a></div><div class="header-nav-menu-item"><a class="header-nav-menu-item__link" href="/archives/"><span class="header-nav-menu-item__icon"><i class="fas fa-folder-open"></i></span><span class="header-nav-menu-item__text">归档</span></a></div><div class="header-nav-menu-item"><a class="header-nav-menu-item__link" href="/categories/"><span class="header-nav-menu-item__icon"><i class="fas fa-layer-group"></i></span><span class="header-nav-menu-item__text">分类</span></a></div><div class="header-nav-menu-item"><a class="header-nav-menu-item__link" href="/tags/"><span class="header-nav-menu-item__icon"><i class="fas fa-tags"></i></span><span class="header-nav-menu-item__text">标签</span></a></div><div class="header-nav-menu-item"><a class="header-nav-menu-item__link" href="/about/"><span class="header-nav-menu-item__icon"><i class="fas fa-address-card"></i></span><span class="header-nav-menu-item__text">关于</span></a></div></div><div class="header-nav-mode"><div class="mode"><div class="mode-track"><span class="mode-track-moon"></span><span class="mode-track-sun"></span></div><div class="mode-thumb"></div></div></div></div></nav><div class="header-banner"><div class="header-banner-info"><div class="header-banner-info__title">ljyxsg的技术成长录</div><div class="header-banner-info__subtitle">亿点点nice的ljy</div></div></div></div></header><main class="main" id="main"><div class="main-inner"><div class="content-wrap" id="content-wrap"><div class="content content-home" id="content"><section class="postlist"><article class="postlist-item post"><header class="post-header"><h1 class="post-title"><a class="post-title__link" href="/2023/02/10/%E4%B8%80%E4%BD%93%E6%9C%BA%E9%80%BB%E8%BE%91%E6%A2%B3%E7%90%86/">[ 文章无标题 ]</a></h1><div class="post-meta"><span class="post-meta-item post-meta-item--createtime"><span class="post-meta-item__icon"><i class="far fa-calendar-plus"></i></span><span class="post-meta-item__info">发表于</span><span class="post-meta-item__value">2023-02-10</span></span><span class="post-meta-item post-meta-item--updatetime"><span class="post-meta-item__icon"><i class="far fa-calendar-check"></i></span><span class="post-meta-item__info">更新于</span><span class="post-meta-item__value">2023-02-10</span></span></div></header><div class="post-body"><div class="post-excerpt">
        <h2 id="1-模型"   >
          <a href="#1-模型" class="heading-link"><i class="fas fa-link"></i></a><a href="#1-模型" class="headerlink" title="1.模型"></a>1.模型</h2>
      
        <h2 id="2-系统"   >
          <a href="#2-系统" class="heading-link"><i class="fas fa-link"></i></a><a href="#2-系统" class="headerlink" title="2.系统"></a>2.系统</h2>
      
        <h2 id="3-排版"   >
          <a href="#3-排版" class="heading-link"><i class="fas fa-link"></i></a><a href="#3-排版" class="headerlink" title="3.排版"></a>3.排版</h2>
      
        <h2 id="4-模板"   >
          <a href="#4-模板" class="heading-link"><i class="fas fa-link"></i></a><a href="#4-模板" class="headerlink" title="4.模板"></a>4.模板</h2>
      </div></div></article><article class="postlist-item post"><header class="post-header"><h1 class="post-title"><a class="post-title__link" href="/2023/02/10/Obsidian%E6%93%8D%E4%BD%9Cmarkdown%E7%9A%84%E5%BF%AB%E6%8D%B7%E9%94%AE%E4%BB%8B%E7%BB%8D/">Obsidian操作markdown的快捷键介绍</a></h1><div class="post-meta"><span class="post-meta-item post-meta-item--createtime"><span class="post-meta-item__icon"><i class="far fa-calendar-plus"></i></span><span class="post-meta-item__info">发表于</span><span class="post-meta-item__value">2023-02-10</span></span><span class="post-meta-item post-meta-item--updatetime"><span class="post-meta-item__icon"><i class="far fa-calendar-check"></i></span><span class="post-meta-item__info">更新于</span><span class="post-meta-item__value">2023-02-10</span></span></div></header><div class="post-body"><div class="post-excerpt">
        <h2 id="开头"   >
          <a href="#开头" class="heading-link"><i class="fas fa-link"></i></a><a href="#开头" class="headerlink" title="开头"></a>开头</h2>
      <p>可以通过设置Obsidian的快捷键设置查看具体快捷键指令。</p>
<img src="/2023/02/10/Obsidian%E6%93%8D%E4%BD%9Cmarkdown%E7%9A%84%E5%BF%AB%E6%8D%B7%E9%94%AE%E4%BB%8B%E7%BB%8D/%E5%BF%AB%E6%8D%B7%E9%94%AE%E8%AE%BE%E7%BD%AE.Obsidian1.png" class="" title="快捷键设置.Obsidian1">

        <h2 id="常用快捷键"   >
          <a href="#常用快捷键" class="heading-link"><i class="fas fa-link"></i></a><a href="#常用快捷键" class="headerlink" title="常用快捷键"></a>常用快捷键</h2>
      <div class="table-container"><table>
<thead>
<tr>
<th>操作</th>
<th>快捷键</th>
</tr>
</thead>
<tbody><tr>
<td>编辑文件名</td>
<td>F2</td>
</tr>
<tr>
<td>插入链接</td>
<td>Ctrl + K</td>
</tr>
<tr>
<td>返回</td>
<td>Ctrl + Alt + &lt;-</td>
</tr>
<tr>
<td>加粗&#x2F;取消加粗</td>
<td>Ctrl + B</td>
</tr>
<tr>
<td>快速切换:打开</td>
<td>Ctrl + O</td>
</tr>
<tr>
<td>命令面板</td>
<td>Ctrl + P</td>
</tr>
<tr>
<td>切换编辑&#x2F;预览视图</td>
<td>Ctrl + E</td>
</tr>
<tr>
<td>切换待办事项状态</td>
<td>Ctrl + L</td>
</tr>
<tr>
<td>倾斜&#x2F;取消倾斜</td>
<td>Ctrl + I</td>
</tr>
<tr>
<td>删除段落</td>
<td>Ctrl + D</td>
</tr>
<tr>
<td>新建标签页</td>
<td>Ctrl + T</td>
</tr>
<tr>
<td>新建笔记</td>
<td>Ctrl + N</td>
</tr>
<tr>
<td>在当前笔记中查找并替换</td>
<td>Ctrl + H</td>
</tr>
<tr>
<td>注释&#x2F;取消注释</td>
<td>Ctrl + D</td>
</tr>
<tr>
<td>最后标签页</td>
<td>Ctrl + 9</td>
</tr>
<tr>
<td>下一个标签页</td>
<td>Ctrl + Tab</td>
</tr>
<tr>
<td>上一个标签页</td>
<td>Ctrl + shift + Tab</td>
</tr>
<tr>
<td>取消关闭标签</td>
<td>Ctrl + shift + T</td>
</tr>
<tr>
<td>关闭当前标签页</td>
<td>Ctrl + W</td>
</tr>
</tbody></table></div>
</div></div></article><article class="postlist-item post"><header class="post-header"><h1 class="post-title"><a class="post-title__link" href="/2023/02/10/%E9%83%A8%E7%BD%B2k3s%E5%92%8Ck9s/">部署k3s和k9s</a></h1><div class="post-meta"><span class="post-meta-item post-meta-item--createtime"><span class="post-meta-item__icon"><i class="far fa-calendar-plus"></i></span><span class="post-meta-item__info">发表于</span><span class="post-meta-item__value">2023-02-10</span></span><span class="post-meta-item post-meta-item--updatetime"><span class="post-meta-item__icon"><i class="far fa-calendar-check"></i></span><span class="post-meta-item__info">更新于</span><span class="post-meta-item__value">2023-02-10</span></span></div></header><div class="post-body"><div class="post-excerpt"><p>k3s是k8s的删减版系统，而k9s是k3s或者k8s的可视化系统，让我们来看下如何安装这两个系统，k3s安装v1.20.15+k3s1版本, k9s安装v0.21.7版本。</p>

        <h2 id="1-k3s安装"   >
          <a href="#1-k3s安装" class="heading-link"><i class="fas fa-link"></i></a><a href="#1-k3s安装" class="headerlink" title="1.k3s安装"></a>1.k3s安装</h2>
      <figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">curl -sfL [https://rancher-mirror.oss-cn-beijing.aliyuncs.com/k3s/k3s-install.sh](https://rancher-mirror.oss-cn-beijing.aliyuncs.com/k3s/k3s-install.sh) | INSTALL_K3S_MIRROR=cn INSTALL_K3S_VERSION=v1.20.15+k3s1 sh -s - --docker</span><br></pre></td></tr></table></div></figure>

        <h2 id="2-k9s安装"   >
          <a href="#2-k9s安装" class="heading-link"><i class="fas fa-link"></i></a><a href="#2-k9s安装" class="headerlink" title="2.k9s安装"></a>2.k9s安装</h2>
      <p>下载安装包解压缩的方式</p>
<figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"># 下载k9s安装包</span><br><span class="line">wget [https://github.com/derailed/k9s/releases/download/v0.21.7/k9s_Linux_x86_64.tar.gz]</span><br><span class="line"># 解压缩k9s</span><br><span class="line">tar -zxf k9s_Linux_x86_64.tar.gz -C /usr/local/bin</span><br><span class="line"># 运行k9s</span><br><span class="line">k9s</span><br></pre></td></tr></table></div></figure></div></div></article><article class="postlist-item post"><header class="post-header"><h1 class="post-title"><a class="post-title__link" href="/2023/02/10/%E6%B2%9F%E9%80%9A%E4%B8%8E%E8%A1%A8%E8%BE%BE%E5%8A%9B/">沟通与表达力</a></h1><div class="post-meta"><span class="post-meta-item post-meta-item--createtime"><span class="post-meta-item__icon"><i class="far fa-calendar-plus"></i></span><span class="post-meta-item__info">发表于</span><span class="post-meta-item__value">2023-02-10</span></span><span class="post-meta-item post-meta-item--updatetime"><span class="post-meta-item__icon"><i class="far fa-calendar-check"></i></span><span class="post-meta-item__info">更新于</span><span class="post-meta-item__value">2023-02-10</span></span></div></header><div class="post-body"><div class="post-excerpt">
        <h2 id="与开源社区相处"   >
          <a href="#与开源社区相处" class="heading-link"><i class="fas fa-link"></i></a><a href="#与开源社区相处" class="headerlink" title="与开源社区相处"></a>与开源社区相处</h2>
      <p>需要机敏、有想法、善于观察、乐于主动参与解决问题；提出有内涵、有趣和有思维激励作用、可以为社区贡献经验的问题，而不是被动索取知识。</p>

        <h2 id="与公司相处"   >
          <a href="#与公司相处" class="heading-link"><i class="fas fa-link"></i></a><a href="#与公司相处" class="headerlink" title="与公司相处"></a>与公司相处</h2>
      <p>公司目的:为市场提供价值，创造收入；<br>个人目的:在为企业服务的过程中自我成长，成为超级个体户,用户较强抗风险能力。<br>针对自我掌握的技能无法灵活运用到工作的解决方案：</p>
<ul>
<li>业务能力,做的事能带来哪些收益；</li>
<li>做的事情以目的为导向；</li>
<li>每周进行阶段性总结；</li>
<li>自我认同接纳。</li>
</ul>

        <h2 id="时间的分配"   >
          <a href="#时间的分配" class="heading-link"><i class="fas fa-link"></i></a><a href="#时间的分配" class="headerlink" title="时间的分配"></a>时间的分配</h2>
      <ol>
<li>自我接纳；</li>
<li>陪伴家人；</li>
<li>自我提升。</li>
</ol>

        <h1 id="即兴表达"   >
          <a href="#即兴表达" class="heading-link"><i class="fas fa-link"></i></a><a href="#即兴表达" class="headerlink" title="即兴表达"></a>即兴表达</h1>
      <ol>
<li>正式场合：<code>观点</code> -&gt; <code>理由</code> -&gt; <code>案例</code> -&gt; <code>观点</code></li>
<li>非正式场合: 学会现场取材 <code>人</code> -&gt; <code>细节</code> -&gt; <code>情绪</code> -&gt; <code>收获</code></li>
<li>了解自己，接纳自己,学会利用自己的优势。</li>
<li>欣赏比较好的表达视频,进行刻意练习。</li>
</ol>

        <h2 id="如何批评别人"   >
          <a href="#如何批评别人" class="heading-link"><i class="fas fa-link"></i></a><a href="#如何批评别人" class="headerlink" title="如何批评别人"></a>如何批评别人</h2>
      <ol>
<li>放弃权力思维(权力不对等), 不要把周围人当成完成工作的工具；</li>
<li>暴力批评的危害: 人产生抵触是因为失去了安全感, 暴力批评会触发人的自我保护意识和损害自尊心。</li>
</ol>

        <h2 id="管理能力"   >
          <a href="#管理能力" class="heading-link"><i class="fas fa-link"></i></a><a href="#管理能力" class="headerlink" title="管理能力"></a>管理能力</h2>
      <p>管理的本质是激发人的善意和潜力。</p>

        <h2 id="说到下属心里去"   >
          <a href="#说到下属心里去" class="heading-link"><i class="fas fa-link"></i></a><a href="#说到下属心里去" class="headerlink" title="说到下属心里去"></a>说到下属心里去</h2>
      <ol>
<li>共情能力:<ul>
<li>我感觉你有什么话没说？</li>
<li>我站在你的角度我也会和你有一样的想法；</li>
<li>让我们想一想要达成你的目标，我们可以指定什么计划。</li>
</ul>
</li>
<li>描述对方的问题, 承认对方的感受，询问对方要怎么做。</li>
</ol>
</div></div></article><article class="postlist-item post"><header class="post-header"><h1 class="post-title"><a class="post-title__link" href="/2023/02/09/%E4%BD%BF%E7%94%A8netty%E5%88%9B%E5%BB%BAhttp%E7%BD%91%E9%A1%B5%E8%81%8A%E5%A4%A9%E5%AE%A4/">使用netty创建http网页聊天室</a></h1><div class="post-meta"><span class="post-meta-item post-meta-item--createtime"><span class="post-meta-item__icon"><i class="far fa-calendar-plus"></i></span><span class="post-meta-item__info">发表于</span><span class="post-meta-item__value">2023-02-09</span></span><span class="post-meta-item post-meta-item--updatetime"><span class="post-meta-item__icon"><i class="far fa-calendar-check"></i></span><span class="post-meta-item__info">更新于</span><span class="post-meta-item__value">2023-02-10</span></span></div></header><div class="post-body"><div class="post-excerpt">
        <h2 id="一、项目简介"   >
          <a href="#一、项目简介" class="heading-link"><i class="fas fa-link"></i></a><a href="#一、项目简介" class="headerlink" title="一、项目简介"></a>一、项目简介</h2>
      <pre><code>创建一个类似微信的基于netty的http网页聊天室。
</code></pre>
<img src="/2023/02/09/%E4%BD%BF%E7%94%A8netty%E5%88%9B%E5%BB%BAhttp%E7%BD%91%E9%A1%B5%E8%81%8A%E5%A4%A9%E5%AE%A4/%E8%81%8A%E5%A4%A9%E5%AE%A4%E6%88%AA%E5%9B%BE.netty1.png" class="" title="聊天室截图.netty1">

        <h2 id="二、项目搭建"   >
          <a href="#二、项目搭建" class="heading-link"><i class="fas fa-link"></i></a><a href="#二、项目搭建" class="headerlink" title="二、项目搭建"></a>二、项目搭建</h2>
      <p>源码地址为：<span class="exturl"><a class="exturl__link"   target="_blank" rel="noopener" href="https://gitee.com/lou_jianyang/netty-springboot" >聊天室netty-springboot</a><span class="exturl__icon"><i class="fas fa-external-link-alt"></i></span></span></p>

        <h2 id="三、导入基础环境"   >
          <a href="#三、导入基础环境" class="heading-link"><i class="fas fa-link"></i></a><a href="#三、导入基础环境" class="headerlink" title="三、导入基础环境"></a>三、导入基础环境</h2>
      <ol>
<li>相关依赖<figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">&lt;!--整合web模块--&gt;  </span><br><span class="line">&lt;dependency&gt;  </span><br><span class="line">    &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;  </span><br><span class="line">    &lt;artifactId&gt;spring-boot-starter-web&lt;/artifactId&gt;  </span><br><span class="line">&lt;/dependency&gt;  </span><br><span class="line">&lt;!--整合模板引擎 --&gt;  </span><br><span class="line">&lt;dependency&gt;  </span><br><span class="line">    &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;  </span><br><span class="line">    &lt;artifactId&gt;spring-boot-starter-thymeleaf&lt;/artifactId&gt;  </span><br><span class="line">&lt;/dependency&gt;  </span><br><span class="line">&lt;dependency&gt;  </span><br><span class="line">    &lt;groupId&gt;org.projectlombok&lt;/groupId&gt;  </span><br><span class="line">    &lt;artifactId&gt;lombok&lt;/artifactId&gt;  </span><br><span class="line">&lt;/dependency&gt;</span><br></pre></td></tr></table></div></figure></li>
<li>静态资源</li>
<li>yaml配置<figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">server:  </span><br><span class="line">  port: 8080  </span><br><span class="line">resources:  </span><br><span class="line">  static-locations:  </span><br><span class="line">    - classpath:/static/  </span><br><span class="line">spring:  </span><br><span class="line">  thymeleaf:  </span><br><span class="line">    cache: false  </span><br><span class="line">    checktemplatelocation: true  </span><br><span class="line">    enabled: true  </span><br><span class="line">    encoding: UTF-8  </span><br><span class="line">    mode: HTML5  </span><br><span class="line">    prefix: classpath:/templates/  </span><br><span class="line">    suffix: .html</span><br></pre></td></tr></table></div></figure></li>
</ol>

        <h2 id="四、服务端开发"   >
          <a href="#四、服务端开发" class="heading-link"><i class="fas fa-link"></i></a><a href="#四、服务端开发" class="headerlink" title="四、服务端开发"></a>四、服务端开发</h2>
      <ol>
<li>添加Netty依赖<figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">&lt;!--引入netty依赖 --&gt;  </span><br><span class="line">&lt;dependency&gt;  </span><br><span class="line">    &lt;groupId&gt;io.netty&lt;/groupId&gt;  </span><br><span class="line">    &lt;artifactId&gt;netty-all&lt;/artifactId&gt;  </span><br><span class="line">&lt;/dependency&gt;</span><br></pre></td></tr></table></div></figure></li>
<li>Netty相关配置<figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">netty:  </span><br><span class="line">  port: 8081  </span><br><span class="line">  path: /chat1</span><br></pre></td></tr></table></div></figure></li>
<li>Netty配置类<figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">package com.ljy.config;  </span><br><span class="line">  </span><br><span class="line">import lombok.Data;  </span><br><span class="line">import org.springframework.boot.context.properties.ConfigurationProperties;  </span><br><span class="line">import org.springframework.stereotype.Component;  </span><br><span class="line">  </span><br><span class="line">@Component  </span><br><span class="line">@ConfigurationProperties(prefix = &quot;netty&quot;)  </span><br><span class="line">@Data  </span><br><span class="line">public class NettyConfig &#123;  </span><br><span class="line">  </span><br><span class="line">    private int port;//netty监听的端口  </span><br><span class="line">  </span><br><span class="line">    private String path;//websocket访问路径  </span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure></li>
<li>NettyWebSocketServer开发<figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br></pre></td><td class="code"><pre><span class="line">package com.ljy.netty;  </span><br><span class="line">  </span><br><span class="line">import com.ljy.config.NettyConfig;  </span><br><span class="line">import io.netty.bootstrap.ServerBootstrap;  </span><br><span class="line">import io.netty.channel.ChannelFuture;  </span><br><span class="line">import io.netty.channel.EventLoopGroup;  </span><br><span class="line">import io.netty.channel.nio.NioEventLoopGroup;  </span><br><span class="line">import io.netty.channel.socket.nio.NioServerSocketChannel;  </span><br><span class="line">import io.netty.handler.logging.LogLevel;  </span><br><span class="line">import io.netty.handler.logging.LoggingHandler;  </span><br><span class="line">import org.springframework.beans.factory.annotation.Autowired;  </span><br><span class="line">import org.springframework.stereotype.Component;  </span><br><span class="line">  </span><br><span class="line">import javax.annotation.PreDestroy;  </span><br><span class="line">  </span><br><span class="line">/**  </span><br><span class="line"> * Netty服务器  </span><br><span class="line"> */  </span><br><span class="line">@Component  </span><br><span class="line">public class NettyWebSocketServer implements Runnable &#123;  </span><br><span class="line">  </span><br><span class="line">    @Autowired  </span><br><span class="line">    NettyConfig nettyConfig;  </span><br><span class="line">  </span><br><span class="line">    @Autowired  </span><br><span class="line">    WebSocketChannelInit webSocketChannelInit;  </span><br><span class="line">  </span><br><span class="line">  </span><br><span class="line">    private EventLoopGroup bossGroup = new NioEventLoopGroup(1);  </span><br><span class="line">  </span><br><span class="line">    private EventLoopGroup workerGroup = new NioEventLoopGroup();  </span><br><span class="line">  </span><br><span class="line">    /**  </span><br><span class="line">     * 资源关闭--在容器销毁是关闭  </span><br><span class="line">     */  </span><br><span class="line">    @PreDestroy  </span><br><span class="line">    public void close() &#123;  </span><br><span class="line">        bossGroup.shutdownGracefully();  </span><br><span class="line">        workerGroup.shutdownGracefully();  </span><br><span class="line">    &#125;  </span><br><span class="line">  </span><br><span class="line">    @Override  </span><br><span class="line">    public void run() &#123;  </span><br><span class="line">        try &#123;  </span><br><span class="line">            //1.创建服务端启动助手  </span><br><span class="line">            ServerBootstrap serverBootstrap = new ServerBootstrap();  </span><br><span class="line">            //2.设置线程组  </span><br><span class="line">            serverBootstrap.group(bossGroup, workerGroup);  </span><br><span class="line">            //3.设置参数  </span><br><span class="line">            serverBootstrap.channel(NioServerSocketChannel.class)  </span><br><span class="line">                    .handler(new LoggingHandler(LogLevel.DEBUG))  </span><br><span class="line">                    .childHandler(webSocketChannelInit);  </span><br><span class="line">            //4.启动  </span><br><span class="line">            ChannelFuture channelFuture = serverBootstrap.bind(nettyConfig.getPort()).sync();  </span><br><span class="line">            System.out.println(&quot;--Netty服务端启动成功---&quot;);  </span><br><span class="line">            channelFuture.channel().closeFuture().sync();  </span><br><span class="line">        &#125; catch (Exception e) &#123;  </span><br><span class="line">            e.printStackTrace();  </span><br><span class="line">            bossGroup.shutdownGracefully();  </span><br><span class="line">            workerGroup.shutdownGracefully();  </span><br><span class="line">        &#125; finally &#123;  </span><br><span class="line">            bossGroup.shutdownGracefully();  </span><br><span class="line">            workerGroup.shutdownGracefully();  </span><br><span class="line">        &#125;  </span><br><span class="line">    &#125;  </span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure></li>
<li>通道初始化对象<figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br></pre></td><td class="code"><pre><span class="line">package com.ljy.netty;  </span><br><span class="line">  </span><br><span class="line">import com.ljy.config.NettyConfig;  </span><br><span class="line">import io.netty.channel.Channel;  </span><br><span class="line">import io.netty.channel.ChannelInitializer;  </span><br><span class="line">import io.netty.channel.ChannelPipeline;  </span><br><span class="line">import io.netty.handler.codec.http.HttpObjectAggregator;  </span><br><span class="line">import io.netty.handler.codec.http.HttpServerCodec;  </span><br><span class="line">import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;  </span><br><span class="line">import io.netty.handler.stream.ChunkedWriteHandler;  </span><br><span class="line">import org.springframework.beans.factory.annotation.Autowired;  </span><br><span class="line">import org.springframework.stereotype.Component;  </span><br><span class="line">  </span><br><span class="line">/**  </span><br><span class="line"> * 通道初始化对象  </span><br><span class="line"> */  </span><br><span class="line">@Component  </span><br><span class="line">public class WebSocketChannelInit extends ChannelInitializer &#123;  </span><br><span class="line">  </span><br><span class="line">    @Autowired  </span><br><span class="line">    NettyConfig nettyConfig;  </span><br><span class="line">  </span><br><span class="line">    @Autowired  </span><br><span class="line">    WebSocketHandler webSocketHandler;  </span><br><span class="line">  </span><br><span class="line">    @Override  </span><br><span class="line">    protected void initChannel(Channel channel) throws Exception &#123;  </span><br><span class="line">        ChannelPipeline pipeline = channel.pipeline();  </span><br><span class="line">        //对http协议的支持.  </span><br><span class="line">        pipeline.addLast(new HttpServerCodec());  </span><br><span class="line">        // 对大数据流的支持  </span><br><span class="line">        pipeline.addLast(new ChunkedWriteHandler());  </span><br><span class="line">        //post请求分三部分. request line / request header / message body  </span><br><span class="line">        // HttpObjectAggregator将多个信息转化成单一的request或者response对象  </span><br><span class="line">        pipeline.addLast(new HttpObjectAggregator(8000));  </span><br><span class="line">        // 将http协议升级为ws协议. websocket的支持  </span><br><span class="line">        pipeline.addLast(new WebSocketServerProtocolHandler(nettyConfig.getPath()));  </span><br><span class="line">        // 自定义处理handler  </span><br><span class="line">        pipeline.addLast(webSocketHandler);  </span><br><span class="line">  </span><br><span class="line">    &#125;  </span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure></li>
<li>处理对象<figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br></pre></td><td class="code"><pre><span class="line">package com.ljy.netty;  </span><br><span class="line">  </span><br><span class="line">import io.netty.channel.Channel;  </span><br><span class="line">import io.netty.channel.ChannelHandler;  </span><br><span class="line">import io.netty.channel.ChannelHandlerContext;  </span><br><span class="line">import io.netty.channel.SimpleChannelInboundHandler;  </span><br><span class="line">import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;  </span><br><span class="line">import org.springframework.stereotype.Component;  </span><br><span class="line">  </span><br><span class="line">import java.util.ArrayList;  </span><br><span class="line">import java.util.List;  </span><br><span class="line">  </span><br><span class="line">/**  </span><br><span class="line"> * 自定义处理类  </span><br><span class="line"> * TextWebSocketFrame: websocket数据是帧的形式处理  </span><br><span class="line"> */  </span><br><span class="line">@Component  </span><br><span class="line">@ChannelHandler.Sharable //设置通道共享  </span><br><span class="line">public class WebSocketHandler extends SimpleChannelInboundHandler&lt;TextWebSocketFrame&gt; &#123;  </span><br><span class="line">  </span><br><span class="line">    public static List&lt;Channel&gt; channelList = new ArrayList&lt;&gt;();  </span><br><span class="line">  </span><br><span class="line">    /**  </span><br><span class="line">     * 通道就绪事件  </span><br><span class="line">     *  </span><br><span class="line">     * @param ctx  </span><br><span class="line">     * @throws Exception  </span><br><span class="line">     */    @Override  </span><br><span class="line">    public void channelActive(ChannelHandlerContext ctx) throws Exception &#123;  </span><br><span class="line">        Channel channel = ctx.channel();  </span><br><span class="line">        //当有新的客户端连接的时候, 将通道放入集合  </span><br><span class="line">        channelList.add(channel);  </span><br><span class="line">        System.out.println(&quot;有新的连接.&quot;);  </span><br><span class="line">    &#125;  </span><br><span class="line">  </span><br><span class="line">  </span><br><span class="line">    /**  </span><br><span class="line">     * 通道未就绪--channel下线  </span><br><span class="line">     *  </span><br><span class="line">     * @param ctx  </span><br><span class="line">     * @throws Exception  </span><br><span class="line">     */    @Override  </span><br><span class="line">    public void channelInactive(ChannelHandlerContext ctx) throws Exception &#123;  </span><br><span class="line">        Channel channel = ctx.channel();  </span><br><span class="line">        //当有客户端断开连接的时候,就移除对应的通道  </span><br><span class="line">        channelList.remove(channel);  </span><br><span class="line">    &#125;  </span><br><span class="line">  </span><br><span class="line">    /**  </span><br><span class="line">     * 读就绪事件  </span><br><span class="line">     *  </span><br><span class="line">     * @param ctx  </span><br><span class="line">     * @param textWebSocketFrame  </span><br><span class="line">     * @throws Exception  </span><br><span class="line">     */    @Override  </span><br><span class="line">    protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame textWebSocketFrame) throws Exception &#123;  </span><br><span class="line">        String msg = textWebSocketFrame.text();  </span><br><span class="line">        System.out.println(&quot;msg:&quot; + msg);  </span><br><span class="line">        //当前发送消息的通道, 当前发送的客户端连接  </span><br><span class="line">        Channel channel = ctx.channel();  </span><br><span class="line">        for (Channel channel1 : channelList) &#123;  </span><br><span class="line">            //排除自身通道  </span><br><span class="line">            if (channel != channel1) &#123;  </span><br><span class="line">                channel1.writeAndFlush(new TextWebSocketFrame(msg));  </span><br><span class="line">            &#125;  </span><br><span class="line">        &#125;  </span><br><span class="line">    &#125;  </span><br><span class="line">  </span><br><span class="line">  </span><br><span class="line">    /**  </span><br><span class="line">     * 异常处理事件  </span><br><span class="line">     *  </span><br><span class="line">     * @param ctx  </span><br><span class="line">     * @param cause  </span><br><span class="line">     * @throws Exception  </span><br><span class="line">     */    @Override  </span><br><span class="line">    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception &#123;  </span><br><span class="line">        cause.printStackTrace();  </span><br><span class="line">        Channel channel = ctx.channel();  </span><br><span class="line">        //移除集合  </span><br><span class="line">        channelList.remove(channel);  </span><br><span class="line">    &#125;  </span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure></li>
<li>启动类<figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line">package com.ljy;  </span><br><span class="line">  </span><br><span class="line">import com.ljy.netty.NettyWebSocketServer;  </span><br><span class="line">import org.springframework.beans.factory.annotation.Autowired;  </span><br><span class="line">import org.springframework.boot.CommandLineRunner;  </span><br><span class="line">import org.springframework.boot.SpringApplication;  </span><br><span class="line">import org.springframework.boot.autoconfigure.SpringBootApplication;  </span><br><span class="line">  </span><br><span class="line">@SpringBootApplication  </span><br><span class="line">public class NettySpringbootApplication implements CommandLineRunner &#123;  </span><br><span class="line">  </span><br><span class="line">    @Autowired  </span><br><span class="line">    NettyWebSocketServer nettyWebSocketServer;  </span><br><span class="line">  </span><br><span class="line">    public static void main(String[] args) &#123;  </span><br><span class="line">        SpringApplication.run(NettySpringbootApplication.class, args);  </span><br><span class="line">    &#125;  </span><br><span class="line">  </span><br><span class="line">    @Override  </span><br><span class="line">    public void run(String... args) throws Exception &#123;  </span><br><span class="line">        new Thread(nettyWebSocketServer).start();  </span><br><span class="line">    &#125;  </span><br><span class="line">&#125;</span><br></pre></td></tr></table></div></figure></li>
<li>前端js开发<figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br></pre></td><td class="code"><pre><span class="line">$(function () &#123;  </span><br><span class="line">    //这里需要注意的是，prompt有两个参数，前面是提示的话，后面是当对话框出来后，在对话框里的默认值  </span><br><span class="line">    var username = &quot;&quot;;  </span><br><span class="line">    while (true) &#123;  </span><br><span class="line">        //弹出一个输入框，输入一段文字，可以提交  </span><br><span class="line">        username = prompt(&quot;请输入您的名字&quot;, &quot;&quot;); //将输入的内容赋给变量 name ，  </span><br><span class="line">        if (username.trim() === &quot;&quot;)//如果返回的有内容  </span><br><span class="line">        &#123;  </span><br><span class="line">            alert(&quot;名称不能输入空&quot;)  </span><br><span class="line">        &#125; else &#123;  </span><br><span class="line">            $(&quot;#username&quot;).text(username);  </span><br><span class="line">            break;        &#125;  </span><br><span class="line">    &#125;  </span><br><span class="line">  </span><br><span class="line">    var ws = new WebSocket(&quot;ws://localhost:8081/chat1&quot;);  </span><br><span class="line">    ws.onopen = function () &#123;  </span><br><span class="line">        console.log(&quot;连接成功.&quot;)  </span><br><span class="line">    &#125;  </span><br><span class="line">    ws.onmessage = function (evt) &#123;  </span><br><span class="line">        showMessage(evt.data);  </span><br><span class="line">    &#125;  </span><br><span class="line">    ws.onclose = function ()&#123;  </span><br><span class="line">        console.log(&quot;连接关闭&quot;)  </span><br><span class="line">    &#125;  </span><br><span class="line">  </span><br><span class="line">    ws.onerror = function ()&#123;  </span><br><span class="line">        console.log(&quot;连接异常&quot;)  </span><br><span class="line">    &#125;  </span><br><span class="line">  </span><br><span class="line">    function showMessage(message) &#123;  </span><br><span class="line">        // 张三:你好  </span><br><span class="line">        var str = message.split(&quot;:&quot;);  </span><br><span class="line">        $(&quot;#msg_list&quot;).append(`&lt;li class=&quot;active&quot;&#125;&gt;  </span><br><span class="line">                                  &lt;div class=&quot;main&quot;&gt;                                    &lt;img class=&quot;avatar&quot; width=&quot;30&quot; height=&quot;30&quot; src=&quot;/img/user.png&quot;&gt;                                    &lt;div&gt;                                        &lt;div class=&quot;user_name&quot;&gt;$&#123;str[0]&#125;&lt;/div&gt;  </span><br><span class="line">                                        &lt;div class=&quot;text&quot;&gt;$&#123;str[1]&#125;&lt;/div&gt;  </span><br><span class="line">                                    &lt;/div&gt;                                   &lt;/div&gt;  </span><br><span class="line">                              &lt;/li&gt;`);  </span><br><span class="line">        // 置底  </span><br><span class="line">        setBottom();  </span><br><span class="line">    &#125;  </span><br><span class="line">  </span><br><span class="line">    $(&#x27;#my_test&#x27;).bind(&#123;  </span><br><span class="line">        focus: function (event) &#123;  </span><br><span class="line">            event.stopPropagation()  </span><br><span class="line">            $(&#x27;#my_test&#x27;).val(&#x27;&#x27;);  </span><br><span class="line">            $(&#x27;.arrow_box&#x27;).hide()  </span><br><span class="line">        &#125;,  </span><br><span class="line">        keydown: function (event) &#123;  </span><br><span class="line">            event.stopPropagation()  </span><br><span class="line">            if (event.keyCode === 13) &#123;  </span><br><span class="line">                if ($(&#x27;#my_test&#x27;).val().trim() === &#x27;&#x27;) &#123;  </span><br><span class="line">                    this.blur()  </span><br><span class="line">                    $(&#x27;.arrow_box&#x27;).show()  </span><br><span class="line">                    setTimeout(() =&gt; &#123;  </span><br><span class="line">                        this.focus()  </span><br><span class="line">                    &#125;, 1000)  </span><br><span class="line">                &#125; else &#123;  </span><br><span class="line">                    $(&#x27;.arrow_box&#x27;).hide()  </span><br><span class="line">                    //发送消息  </span><br><span class="line">                    sendMsg();  </span><br><span class="line">                    this.blur()  </span><br><span class="line">                    setTimeout(() =&gt; &#123;  </span><br><span class="line">                        this.focus()  </span><br><span class="line">                    &#125;)  </span><br><span class="line">                &#125;  </span><br><span class="line">            &#125;  </span><br><span class="line">        &#125;  </span><br><span class="line">    &#125;);  </span><br><span class="line">    $(&#x27;#send&#x27;).on(&#x27;click&#x27;, function (event) &#123;  </span><br><span class="line">        event.stopPropagation()  </span><br><span class="line">        if ($(&#x27;#my_test&#x27;).val().trim() === &#x27;&#x27;) &#123;  </span><br><span class="line">            $(&#x27;.arrow_box&#x27;).show()  </span><br><span class="line">        &#125; else &#123;  </span><br><span class="line">            sendMsg();  </span><br><span class="line">        &#125;  </span><br><span class="line">    &#125;)  </span><br><span class="line">  </span><br><span class="line">    function sendMsg() &#123;  </span><br><span class="line">        var message = $(&quot;#my_test&quot;).val();  </span><br><span class="line">        $(&quot;#msg_list&quot;).append(`&lt;li class=&quot;active&quot;&#125;&gt;  </span><br><span class="line">                                  &lt;div class=&quot;main self&quot;&gt;                                      &lt;div class=&quot;text&quot;&gt;` + message + `&lt;/div&gt;  </span><br><span class="line">                                  &lt;/div&gt;                              &lt;/li&gt;`);  </span><br><span class="line">        $(&quot;#my_test&quot;).val(&#x27;&#x27;);  </span><br><span class="line">  </span><br><span class="line">        //发送消息  </span><br><span class="line">        message = username + &quot;:&quot; + message;  </span><br><span class="line">        ws.send(message);  </span><br><span class="line">        // 置底  </span><br><span class="line">        setBottom();  </span><br><span class="line">    &#125;  </span><br><span class="line">  </span><br><span class="line">    // 置底  </span><br><span class="line">    function setBottom() &#123;  </span><br><span class="line">        // 发送消息后滚动到底部  </span><br><span class="line">        const container = $(&#x27;.m-message&#x27;)  </span><br><span class="line">        const scroll = $(&#x27;#msg_list&#x27;)  </span><br><span class="line">        container.animate(&#123;  </span><br><span class="line">            scrollTop: scroll[0].scrollHeight - container[0].clientHeight + container.scrollTop() + 100  </span><br><span class="line">        &#125;);  </span><br><span class="line">    &#125;  </span><br><span class="line">&#125;);</span><br></pre></td></tr></table></div></figure></li>
</ol>
</div></div></article><article class="postlist-item post"><header class="post-header"><h1 class="post-title"><a class="post-title__link" href="/2023/02/07/datax%E6%89%A7%E8%A1%8C%E6%95%B0%E9%87%87%E4%BB%BB%E5%8A%A1%E7%A4%BA%E4%BE%8B/">datax执行数采任务示例</a></h1><div class="post-meta"><span class="post-meta-item post-meta-item--createtime"><span class="post-meta-item__icon"><i class="far fa-calendar-plus"></i></span><span class="post-meta-item__info">发表于</span><span class="post-meta-item__value">2023-02-07</span></span><span class="post-meta-item post-meta-item--updatetime"><span class="post-meta-item__icon"><i class="far fa-calendar-check"></i></span><span class="post-meta-item__info">更新于</span><span class="post-meta-item__value">2023-02-07</span></span></div></header><div class="post-body"><div class="post-excerpt">
        <h2 id="一-创建一个数采任务并执行"   >
          <a href="#一-创建一个数采任务并执行" class="heading-link"><i class="fas fa-link"></i></a><a href="#一-创建一个数采任务并执行" class="headerlink" title="一.创建一个数采任务并执行"></a>一.创建一个数采任务并执行</h2>
      
        <h3 id="1）创建一个项目"   >
          <a href="#1）创建一个项目" class="heading-link"><i class="fas fa-link"></i></a><a href="#1）创建一个项目" class="headerlink" title="1）创建一个项目"></a>1）创建一个项目</h3>
      <ul>
<li>1.项目管理 -&gt; 输入项目名称、项目描述<img src="/2023/02/07/datax%E6%89%A7%E8%A1%8C%E6%95%B0%E9%87%87%E4%BB%BB%E5%8A%A1%E7%A4%BA%E4%BE%8B/%E9%A1%B9%E7%9B%AE.example1.png" class="" title="项目.example1"></li>
<li>2.创建数据源:<br>  本示例创建<code>mysql</code>和<code>clickhouse</code>两个数据源,<code>mysql</code>数据源用来读取,<code>clickhouse</code>用来写入。<br>  如何添加添加数据源:<code>数据源管理</code> -&gt; <code>选择数据源</code>:clickhouse -&gt; <code>输入数据源名称</code>:test -&gt; <code>用户名</code> -&gt; <code>密码</code> -&gt; <code>jdbc_url</code>:jdbc:clickhouse:&#x2F;&#x2F;192.168.13.46:8123&#x2F;default -&gt; <code>jbdc驱动类</code> -&gt; <code>测试连接</code>。如果出现连接成功的弹框,那说明数据源已经配置成功了。<img src="/2023/02/07/datax%E6%89%A7%E8%A1%8C%E6%95%B0%E9%87%87%E4%BB%BB%E5%8A%A1%E7%A4%BA%E4%BE%8B/%E6%95%B0%E6%8D%AE%E6%BA%90%E9%85%8D%E7%BD%AE.example2.png" class="" title="数据源配置.example2"></li>
<li>3.创建DataX任务模板:<code>添加</code> -&gt; <code>执行器</code> -&gt; <code>路由策略</code> -&gt; <code>阻塞处理</code> -&gt; <code>任务类型</code> -&gt; <code>所属项目</code> -&gt; <code>任务描述</code> -&gt; <code>Cron定时表达式</code> -&gt; <code>点击确认</code><img src="/2023/02/07/datax%E6%89%A7%E8%A1%8C%E6%95%B0%E9%87%87%E4%BB%BB%E5%8A%A1%E7%A4%BA%E4%BE%8B/DataX%E4%BB%BB%E5%8A%A1%E6%A8%A1%E6%9D%BF.example4.png" class="" title="DataX任务模板.example4"></li>
<li>4.任务构建(分为4个步骤)<ul>
<li>1.在<code>mysql</code>和<code>clickhouse</code>里创建示例表，表名和字段名均可不一致</li>
<li>1.构建reader:选择<code>数据库源</code> -&gt; <code>数据库表名</code> -&gt; 选择要读取的<code>表字段</code></li>
<li>2.构建writer:选择<code>数据库源</code> -&gt; <code>数据库表名</code> -&gt; 选择要写入的<code>表字段</code></li>
<li>3.字段映射:选择需要<code>读取字段和写入字段</code></li>
<li>4.<code>点击构建</code> -&gt; <code>选择模板</code><br>  创建完成可以在任务管理中找到任务记录。<img src="/2023/02/07/datax%E6%89%A7%E8%A1%8C%E6%95%B0%E9%87%87%E4%BB%BB%E5%8A%A1%E7%A4%BA%E4%BE%8B/%E4%BB%BB%E5%8A%A1%E7%AE%A1%E7%90%86.example3.png" class="" title="任务管理.example3"></li>
</ul>
</li>
</ul>

        <h2 id="2）运行一次数采任务"   >
          <a href="#2）运行一次数采任务" class="heading-link"><i class="fas fa-link"></i></a><a href="#2）运行一次数采任务" class="headerlink" title="2）运行一次数采任务"></a>2）运行一次数采任务</h2>
      <ul>
<li><code>任务管理</code> -&gt; <code>操作</code> -&gt; <code>执行一次</code><img src="/2023/02/07/datax%E6%89%A7%E8%A1%8C%E6%95%B0%E9%87%87%E4%BB%BB%E5%8A%A1%E7%A4%BA%E4%BE%8B/%E6%93%8D%E4%BD%9C%E4%BB%BB%E5%8A%A1.example5.png" class="" title="操作任务.example5">
使用<code>dbeaver</code>连接<code>clickhouse</code>，可以看到数据已经采集完成。</li>
</ul>
</div></div></article><article class="postlist-item post"><header class="post-header"><h1 class="post-title"><a class="post-title__link" href="/2023/02/07/datax%E6%95%B0%E6%8D%AE%E5%BA%93%E8%AE%BE%E8%AE%A1/">datax数据库设计</a></h1><div class="post-meta"><span class="post-meta-item post-meta-item--createtime"><span class="post-meta-item__icon"><i class="far fa-calendar-plus"></i></span><span class="post-meta-item__info">发表于</span><span class="post-meta-item__value">2023-02-07</span></span><span class="post-meta-item post-meta-item--updatetime"><span class="post-meta-item__icon"><i class="far fa-calendar-check"></i></span><span class="post-meta-item__info">更新于</span><span class="post-meta-item__value">2023-02-07</span></span></div></header><div class="post-body"><div class="post-excerpt"><img src="/2023/02/07/datax%E6%95%B0%E6%8D%AE%E5%BA%93%E8%AE%BE%E8%AE%A1/datax%E6%95%B0%E6%8D%AE%E5%BA%93%E6%A8%A1%E5%9E%8B.db1.png" class="" title="datax数据库模型.db1">
<p>datax总共有张表</p>
<ul>
<li>1.job_group:任务组</li>
<li>2.job_info:任务信息</li>
<li>3.job_jdbc_datasource:任务数据源配置</li>
<li>4.job_lock:任务锁</li>
<li>5.job_log:任务日志</li>
<li>6.job_log_report:任务日志报告</li>
<li>7.job_logglue:任务日志胶水</li>
<li>8.job_permission:任务权限</li>
<li>9.job_project:任务项目</li>
<li>10.job_registry:任务注册中心</li>
<li>11.job_template:任务模板</li>
<li>12.job_user:任务用户<br>其中第7张表job_logglue可以暂时不看,目前项目中仅支持以bean的方式加载任务。</li>
</ul>
</div></div></article><article class="postlist-item post"><header class="post-header"><h1 class="post-title"><a class="post-title__link" href="/2023/02/03/windows%E5%AE%89%E8%A3%85sql-Server-2017-latest/">windows安装sql Server:2017-latest</a></h1><div class="post-meta"><span class="post-meta-item post-meta-item--createtime"><span class="post-meta-item__icon"><i class="far fa-calendar-plus"></i></span><span class="post-meta-item__info">发表于</span><span class="post-meta-item__value">2023-02-03</span></span><span class="post-meta-item post-meta-item--updatetime"><span class="post-meta-item__icon"><i class="far fa-calendar-check"></i></span><span class="post-meta-item__info">更新于</span><span class="post-meta-item__value">2023-02-10</span></span></div></header><div class="post-body"><div class="post-excerpt">
        <h2 id="1-下载sql-server-2017"   >
          <a href="#1-下载sql-server-2017" class="heading-link"><i class="fas fa-link"></i></a><a href="#1-下载sql-server-2017" class="headerlink" title="1.下载sql server:2017"></a>1.下载sql server:2017</h2>
      <p>首先打开windows本地的docker desktop，打开windows的ubuntu子系统，输入以下命令:</p>
<figure class="highlight sh"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker pull mcr.microsoft.com/mssql/server:2017-latest</span><br></pre></td></tr></table></div></figure>

        <h2 id="2-使用docker运行容器镜像"   >
          <a href="#2-使用docker运行容器镜像" class="heading-link"><i class="fas fa-link"></i></a><a href="#2-使用docker运行容器镜像" class="headerlink" title="2.使用docker运行容器镜像"></a>2.使用docker运行容器镜像</h2>
      <figure class="highlight sh"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">docker run -e <span class="string">&quot;ACCEPT_EULA=Y&quot;</span> -e <span class="string">&quot;SA_PASSWORD=YourNewStrong@Passw0rd&quot;</span> \</span><br><span class="line">	-p 1433:1433 --name mssql \</span><br><span class="line">	-d mcr.microsoft.com/mssql/server:2017-latest</span><br></pre></td></tr></table></div></figure>

        <h2 id="3-navicat连接sqlServer"   >
          <a href="#3-navicat连接sqlServer" class="heading-link"><i class="fas fa-link"></i></a><a href="#3-navicat连接sqlServer" class="headerlink" title="3.navicat连接sqlServer"></a>3.navicat连接sqlServer</h2>
      <p><code>连接名</code> -&gt; <code>主机</code> -&gt; <code>初始数据库</code> -&gt; <code>SQL Server 验证</code> -&gt; <code>用户名</code> -&gt; <code>密码</code> -&gt; <code>测试连接</code></p>

</div></div></article><article class="postlist-item post"><header class="post-header"><h1 class="post-title"><a class="post-title__link" href="/2023/02/02/Session%E3%80%81Token%E5%92%8CCookie%E7%9A%84%E7%90%86%E8%A7%A3/">Session、Token和Cookie的理解</a></h1><div class="post-meta"><span class="post-meta-item post-meta-item--createtime"><span class="post-meta-item__icon"><i class="far fa-calendar-plus"></i></span><span class="post-meta-item__info">发表于</span><span class="post-meta-item__value">2023-02-02</span></span><span class="post-meta-item post-meta-item--updatetime"><span class="post-meta-item__icon"><i class="far fa-calendar-check"></i></span><span class="post-meta-item__info">更新于</span><span class="post-meta-item__value">2023-02-06</span></span></div></header><div class="post-body"><div class="post-excerpt">
        <h2 id="Session、Token和Cookie的理解"   >
          <a href="#Session、Token和Cookie的理解" class="heading-link"><i class="fas fa-link"></i></a><a href="#Session、Token和Cookie的理解" class="headerlink" title="Session、Token和Cookie的理解"></a>Session、Token和Cookie的理解</h2>
      
        <h3 id="一、现状分析"   >
          <a href="#一、现状分析" class="heading-link"><i class="fas fa-link"></i></a><a href="#一、现状分析" class="headerlink" title="一、现状分析"></a>一、现状分析</h3>
      <p>​ 随着交互式Web应用的兴起，像在线购物网站，需要登录的网站等，会面临一个问题，那就是管理会话，必须记住哪些人登录系统，哪些人往自己的购物车中放商品，也就是说必须把每个人区分开，这是一个挑战，因为HTTP请求是无状态的，一个解决的办法就是发一个会话标识(session id),就是一个随机的子串，每个人收到的都不一样，每次大家向服务器发起HTTP请求的时候，把这个字符串一起发过来，服务器就能区分是谁发起的请求。</p>
<p>​ 这对服务器来说是一个巨大的开销，严重的限制了服务器扩展能力，每个人只需要保存自己的session id,而服务器要保存所有人的session id。</p>

        <h3 id="二、解决方案"   >
          <a href="#二、解决方案" class="heading-link"><i class="fas fa-link"></i></a><a href="#二、解决方案" class="headerlink" title="二、解决方案"></a>二、解决方案</h3>
      <ul>
<li>Cookie:<ul>
<li>浏览器中能永久存储的一种数据，仅仅是浏览器实现的一种数据存储功能。</li>
<li>cookie由服务器生成，发送给浏览器，浏览器把cookie以kv形式保存到某个目录下的文本文件内，下一次请求同一url时会把cookie发送给服务器。</li>
<li>浏览器加入了一些限制确保cookie不会被恶意使用。</li>
</ul>
</li>
<li>Session<ul>
<li>服务器使用session把用户的信息临时保存在服务器上，用户离开网站后session会被销毁，这种用户信息存储方式相对cookie更安全；</li>
<li>如果web服务器做了负载均衡，那么下一个操作请求到了另一台服务器时session会丢失。</li>
</ul>
</li>
<li>Token<ul>
<li><p>基于服务器验证方式(如Session)的问题：</p>
<ul>
<li>每次认证用户发出的请求时，都要创建一个记录来存储信息，会加大内存的开销。</li>
<li>CORS(跨域资源共享)：让数据跨多台移动设备使用时，跨域资源的共享是一个挑战如在使用Ajax抓取另一个域的资源，就会出现禁止请求的情况。</li>
<li>CSRF(跨站请求伪造)：用户在访问银行网站时，很容易受到跨站请求伪造的攻击，并且能够被利用其访问其他网站。</li>
</ul>
</li>
<li><p>基于Token的身份验证过程如下：</p>
<ul>
<li>1、用户通过用户名和密码发送请求。</li>
<li>2、后端程序验证；</li>
<li>3、后端程序返回一个签名的token给客户端；</li>
<li>4、客户端存储token，并且每次用于发送请求；</li>
<li>5、服务端验证token并返回数据。</li>
<li>每一次请求都需要token，token应该在HTTP的头部发送从而保证了Http请求无状态。</li>
</ul>
</li>
</ul>
</li>
</ul>
<img src="/2023/02/02/Session%E3%80%81Token%E5%92%8CCookie%E7%9A%84%E7%90%86%E8%A7%A3/token%E9%AA%8C%E8%AF%81%E8%BF%87%E7%A8%8B.png" class="" title="token验证过程"></div></div></article><article class="postlist-item post"><header class="post-header"><h1 class="post-title"><a class="post-title__link" href="/2023/02/02/datax%E5%AD%A6%E4%B9%A0%E6%89%8B%E5%86%8C/">datax学习手册</a></h1><div class="post-meta"><span class="post-meta-item post-meta-item--createtime"><span class="post-meta-item__icon"><i class="far fa-calendar-plus"></i></span><span class="post-meta-item__info">发表于</span><span class="post-meta-item__value">2023-02-02</span></span><span class="post-meta-item post-meta-item--updatetime"><span class="post-meta-item__icon"><i class="far fa-calendar-check"></i></span><span class="post-meta-item__info">更新于</span><span class="post-meta-item__value">2023-02-07</span></span></div></header><div class="post-body"><div class="post-excerpt">
        <h2 id="1-docker-desktop安装mysql-8-0-16、sql-Server-2017-latest和clickhouse-latest"   >
          <a href="#1-docker-desktop安装mysql-8-0-16、sql-Server-2017-latest和clickhouse-latest" class="heading-link"><i class="fas fa-link"></i></a><a href="#1-docker-desktop安装mysql-8-0-16、sql-Server-2017-latest和clickhouse-latest" class="headerlink" title="1.docker desktop安装mysql:8.0.16、sql Server:2017-latest和clickhouse:latest"></a>1.docker desktop安装mysql:8.0.16、sql Server:2017-latest和clickhouse:latest</h2>
      <p>mysql安装比较简单，在此略过;sql Server的安装见<a href="https://lou_jianyang.gitee.io/2023/02/03/windows%E5%AE%89%E8%A3%85sql-Server-2017-latest/">sql Server2017-latest安装</a>。<br>clickhouse的安装可以借鉴:<span class="exturl"><a class="exturl__link"   target="_blank" rel="noopener" href="https://blog.csdn.net/jianzhang11/article/details/105445855" >clickhouse安装步骤</a><span class="exturl__icon"><i class="fas fa-external-link-alt"></i></span></span>。</p>

        <h2 id="2-在github下载datax-web和datax-web-ui项目"   >
          <a href="#2-在github下载datax-web和datax-web-ui项目" class="heading-link"><i class="fas fa-link"></i></a><a href="#2-在github下载datax-web和datax-web-ui项目" class="headerlink" title="2.在github下载datax_web和datax_web_ui项目"></a>2.在github下载datax_web和datax_web_ui项目</h2>
      <p>建议把项目先fork到自己的仓库(很久没维护了，你懂得)</p>
<figure class="highlight plaintext"><div class="table-container"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">git clone git@github.com:WeiYe-Jing/datax-web.git</span><br><span class="line">git clone git@github.com:WeiYe-Jing/datax-web-ui.git</span><br><span class="line"></span><br></pre></td></tr></table></div></figure>
<p>安装官网指引下载datax工具包,见<span class="exturl"><a class="exturl__link"   target="_blank" rel="noopener" href="https://github.com/alibaba/DataX/blob/master/userGuid.md" >Datax下载方法</a><span class="exturl__icon"><i class="fas fa-external-link-alt"></i></span></span></p>

        <h2 id="3-datax架构图"   >
          <a href="#3-datax架构图" class="heading-link"><i class="fas fa-link"></i></a><a href="#3-datax架构图" class="headerlink" title="3.datax架构图"></a>3.datax架构图</h2>
      <img src="/2023/02/02/datax%E5%AD%A6%E4%B9%A0%E6%89%8B%E5%86%8C/datax%E6%9E%B6%E6%9E%84%E5%9B%BE.png" class="" title="datax架构图">
<p>DataX Web是在DataX之上开发的分布式数据同步工具，提供简单易用的 操作界面，降低用户使用DataX的学习成本，缩短任务配置时间，避免配置过程中出错。用户可通过页面选择数据源即可创建数据同步任务，支持RDBMS、Hive、HBase、ClickHouse、MongoDB等数据源，RDBMS数据源可批量创建数据同步任务，支持实时查看数据同步进度及日志并提供终止同步功能，集成并二次开发xxl-job可根据时间、自增主键增量同步数据。</p>
<p>任务”执行器”支持集群部署，支持执行器多节点路由策略选择，支持超时控制、失败重试、失败告警、任务依赖，执行器CPU.内存.负载的监控等等。后续还将提供更多的数据源支持、数据转换UDF、表结构同步、数据同步血缘等更为复杂的业务场景。<br><code>如何创建一个任务</code>指南见<span class="exturl"><a class="exturl__link"   target="_blank" rel="noopener" href="https://github.com/WeiYe-Jing/datax-web" >datax-web基本使用</a><span class="exturl__icon"><i class="fas fa-external-link-alt"></i></span></span></p>

        <h2 id="4-datax服务启动"   >
          <a href="#4-datax服务启动" class="heading-link"><i class="fas fa-link"></i></a><a href="#4-datax服务启动" class="headerlink" title="4.datax服务启动"></a>4.datax服务启动</h2>
      <ol>
<li>datax包含两个服务datax-admin和datax-executor，这两个服务是有先后启动顺序的，先启动datax-executor，才能启动datax-admin。启动前需要修改这两个服务的application.yml配置文件，datax-executor服务占用了两个端口，8082是datax-executor启动服务的端口,9999是datax执行器的端口。</li>
<li><code>datax-web-ui</code>部署,见<span class="exturl"><a class="exturl__link"   target="_blank" rel="noopener" href="https://github.com/WeiYe-Jing/datax-web-ui" >datax-ui的部署</a><span class="exturl__icon"><i class="fas fa-external-link-alt"></i></span></span></li>
<li>本地运行两个后端服务和一个前端服务, <code>localhost:8082</code>进入前端登录页面 <code>账号:admin</code> -&gt; <code>密码:123456</code>,可以进入到如下的首页:<img src="/2023/02/02/datax%E5%AD%A6%E4%B9%A0%E6%89%8B%E5%86%8C/datax-ui%E9%A6%96%E9%A1%B5.png" class="" title="datax-ui首页"></li>
</ol>
</div></div></article></section><nav class="paginator"><div class="paginator-inner"><span class="page-number current">1</span><a class="page-number" href="/page/2/">2</a><a class="extend next" rel="next" href="/page/2/"><i class="fas fa-angle-right"></i></a></div></nav></div></div><div class="sidebar-wrap" id="sidebar-wrap"><aside class="sidebar" id="sidebar"><section class="sidebar-toc hide"></section><!-- ov = overview--><section class="sidebar-ov"><div class="sidebar-ov-author"><div class="sidebar-ov-author__avatar"><img class="sidebar-ov-author__avatar_img" src="/images/icons/stun-logo.svg" alt="avatar"></div><p class="sidebar-ov-author__text">Hello Stun</p></div><div class="sidebar-ov-state"><a class="sidebar-ov-state-item sidebar-ov-state-item--posts" href="/archives/"><div class="sidebar-ov-state-item__count">15</div><div class="sidebar-ov-state-item__name">归档</div></a><a class="sidebar-ov-state-item sidebar-ov-state-item--categories" href="/categories/"><div class="sidebar-ov-state-item__count">9</div><div class="sidebar-ov-state-item__name">分类</div></a><a class="sidebar-ov-state-item sidebar-ov-state-item--tags" href="/tags/"><div class="sidebar-ov-state-item__count">2</div><div class="sidebar-ov-state-item__name">标签</div></a></div><div class="sidebar-ov-cc"><a href="https://creativecommons.org/licenses/by-nc-sa/4.0/deed.en" target="_blank" rel="noopener" data-popover="知识共享许可协议" data-popover-pos="up"><img src="/images/cc-by-nc-sa.svg"></a></div></section></aside></div><div class="clearfix"></div></div></main><footer class="footer" id="footer"><div class="footer-inner"><div><span>Copyright © 2023</span><span class="footer__icon"><i class="fas fa-heart"></i></span><span>ljyxsg</span></div><div><span>由 <a href="http://hexo.io/" title="Hexo" target="_blank" rel="noopener">Hexo</a> 强力驱动</span><span> v6.3.0</span><span class="footer__devider">|</span><span>主题 - <a href="https://github.com/liuyib/hexo-theme-stun/" title="Stun" target="_blank" rel="noopener">Stun</a></span><span> v2.8.0</span></div></div></footer><div class="loading-bar" id="loading-bar"><div class="loading-bar__progress"></div></div><div class="back2top" id="back2top"><span class="back2top__icon"><i class="fas fa-rocket"></i></span></div></div><script src="https://cdn.jsdelivr.net/npm/jquery@v3.4.1/dist/jquery.min.js"></script><script src="https://cdn.jsdelivr.net/npm/velocity-animate@1.5.2/velocity.min.js"></script><script src="https://cdn.jsdelivr.net/npm/velocity-animate@1.5.2/velocity.ui.min.js"></script><script src="/js/utils.js?v=2.8.0"></script><script src="/js/stun-boot.js?v=2.8.0"></script><script src="/js/scroll.js?v=2.8.0"></script><script src="/js/header.js?v=2.8.0"></script><script src="/js/sidebar.js?v=2.8.0"></script></body></html>